package com.shield.framework.config;

import com.shield.framework.security.auth.ShieldAuthHandler;
import com.shield.framework.security.auth.ShieldAuthenticationEntryPoint;
import com.shield.framework.security.authentication.ShieldAuthenticationTokenFilter;
import com.shield.framework.security.service.ShieldUserDetailsService;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

/**
 * @description: Spring Security 权限控制
 * @Author Andy
 */
@EnableWebSecurity
@RequiredArgsConstructor
@Configuration(proxyBeanMethods = false)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ShieldSecurityConfig  extends WebSecurityConfigurerAdapter {


    private final ShieldUserDetailsService userDetailsService;
    private final ShieldAuthHandler authHandler;
    private final ShieldAuthenticationTokenFilter shieldJwtAuthenticationTokenFilter;

    @Override
    public void configure(WebSecurity web) {
        // @formatter:off
        web.ignoring()
                .antMatchers(HttpMethod.OPTIONS, "/**");
        // @formatter:on
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        // 关闭 csrf、iframe、session
            http.csrf()
                .disable()
                .headers()
                .frameOptions()
                .disable()
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

            http.authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .exceptionHandling()
                .authenticationEntryPoint(new ShieldAuthenticationEntryPoint())
                .accessDeniedHandler(authHandler);


            //走security username password filter流程
            http.formLogin()
                .loginProcessingUrl("/token")
                .failureHandler(authHandler)
                .successHandler(authHandler)
                .permitAll();


            // jwt 认证的 filter
            http.addFilterAt(shieldJwtAuthenticationTokenFilter, BasicAuthenticationFilter.class)
                .userDetailsService(userDetailsService);
            // @formatter:on
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

   /* public static void main(String[] args) {

       System.out.println( Base64.getEncoder().encodeToString(Keys.secretKeyFor(SignatureAlgorithm.HS256).getEncoded()));
    }*/


}
